http://blog.dhananjaynene.com/tags/functional-programming/
Ciastocna aplikacia transformuje funkciu s nejakym poctom parametrov na inu funkciu s mensim poctom parametrov
Cize zafixuje nejake parametre
f:(X × Y × Z) → N
partial(f):(Y × Z) → N
In [ ]:
def add(a, b):
return a + b
In [ ]:
def make_adder(a) :
def adder(b) :
return add(a, b)
return adder
In [ ]:
add_two = make_adder(20)
add_two(4)
In [ ]:
def make_power(exponent):
def power(x):
return x**exponent
return power
In [ ]:
square = make_power(2)
print(square(3))
print(square(30))
square(300)
In [ ]:
from functools import partial
def power(base, exponent):
return base ** exponent
cube = partial(power, 3)
cube(2)
In [ ]:
def power(base, exponent):
return base ** exponent
cube = partial(power, exponent=3)
cube(2)
In [ ]:
basetwo = partial(int, base=2)
basetwo('111010101')
In [ ]:
import sys
from functools import partial
print_stderr = partial(print, file=sys.stderr)
In [ ]:
print_stderr("pokus")
In [ ]:
# print_stderr = partial(print, file=sys.stderr)
print_stderr = lambda x: print(x, file=sys.stderr)
print_stderr('hahahhaha')
In [ ]:
for text in lines:
if re.search('[a-zA-Z]\=', text):
some_action(text)
elif re.search('[a-zA-Z]\s\=', text):
some_other_action(text)
else:
some_default_action()
In [ ]:
def is_grouped_together(text): # skuste z tohoto spravit partial
return re.search("[a-zA-Z]\s\=", text)
def is_spaced_apart(text):
return re.search("[a-zA-Z]\s\=", text)
def and_so_on(text):
return re.search("pattern_188364625", text)
for text in lines:
if is_grouped_together(text):
some_action(text)
elif is_spaced_apart(text):
some_other_action(text)
else:
some_default_action()
In [ ]:
is_spaced_apart = partial(re.search, '[a-zA-Z]\s\=')
is_grouped_together = partial(re.search, '[a-zA-Z]\=')
for text in lines:
if is_grouped_together(text):
some_action(text)
elif is_spaced_apart(text):
some_other_action(text)
else:
some_default_action()
http://chriskiehl.com/article/Cleaner-coding-through-partially-applied-functions/
In [ ]:
class Tovar:
def __init__(self, typ, mnozstvo=0):
self.typ=typ
self.mnozstvo=mnozstvo
def write(self):
return '{}: {}'.format(self.typ, self.mnozstvo)
nakup_jablk = Tovar('jablka', 3)
print(nakup_jablk.write())
In [ ]:
Jablko = partial(Tovar, 'jablka')
Jablko(4).write()
In [ ]:
import pyrsistent as ps
def Tovar(typ, mnozstvo):
def write():
return '{}: {}'.format(typ, mnozstvo)
return ps.freeze({'write': write})
In [ ]:
Jablko = partial(Tovar, 'jablka')
Jablko(5).write()
Kolko krat sa vam stalo, ze ste vedeli davno v programe aku funkciu budete musiet zavolat a aj s castou argumentov, ale museli ste cakat az do nejakeho casu, kde ste dostali aj zvysok a museli ste parametre predavat spolu s funkciou / objektom na ktorom bola metoda
Ak by ste vedeli vyrobit funkciu, s niektorymi parametrami prednastavenymi, tak by vam stacilo posuvat si tuto jednu funkciu a nemuseli by ste si presuvat vsetky parametre az do miesta, kde ich nakoniec vlozite pri volani funkcie
In [ ]:
def query_database(userid, password, query) :
# do query
# return results
def bar(userid, password):
return query_database(userid, password)
def foo(userid, password) :
return bar(userid, password)
def main(userid, password) :
# .. lot of code here .. eventually reaching
foo(userid, password)
In [ ]:
def get_query_agent(userid, password)
def do_query(query) :
# do query
# return results
return do_query
def bar(querying_func):
return func(querying_func)
def foo(querying_func) :
return bar(querying_func)
def main(userid, password) :
query_agent = get_query_agent(userid, password)
# .. much further down the line
foo(query_agent)
http://blog.efftinge.de/2010/03/multiple-dispatch-and-poor-mens-patter.html odkaz davam hlavne kvoli nazvu clanku :)
In [ ]:
# -- JAVA --
static void print(Fruit f) {
sysout("Hello Fruit");
}
static void print(Banana b) {
sysout("Hello Banana");
}
Banana banana = new Fruit();
print(banana)
preto by sa vypisalo "Hello banana" na zaklade typu premennej a nie "Hello Fruit" na zaklade typu objektu
multiple dispatch sa rozhoduje dynamicky na zaklade objektu
Multiple dispatch by som dosiahol napriklad ak by print bola metoda objektu.
In [ ]:
def pokus(a):
print('pokus1')
def pokus():
print('pokus2')
pokus()
In [ ]:
def pokus(a:str, b:list):
print('pokus1')
def pokus(b:int):
print('pokus2')
pokus('3', [])
http://www.grantjenks.com/docs/pypatt-python-pattern-matching/
In [ ]:
# casto sa stava, ze kod vyzera nejak takto
def foo(a, b):
if isinstance(a, int) and isinstance(b, int):
# ...code for two ints...
elif isinstance(a, float) and isinstance(b, float):
# ...code for two floats...
elif isinstance(a, str) and isinstance(b, str):
# ...code for two strings...
else:
raise TypeError("unsupported argument types (%s, %s)" % (type(a), type(b)))
In [ ]:
registry = {}
class MultiMethod(object):
def __init__(self, name):
self.name = name
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args) # a generator expression!
function = self.typemap.get(types)
if function is None:
raise TypeError("no match")
return function(*args)
def register(self, types, function):
if types in self.typemap:
raise TypeError("duplicate registration")
self.typemap[types] = function
def multimethod(*types):
def register(function):
name = function.__name__
mm = registry.get(name)
if mm is None:
mm = registry[name] = MultiMethod(name)
mm.register(types, function)
return mm
return register
In [ ]:
@multimethod(int, int)
def foo(a, b):
print('int int')
@multimethod(float, float)
def foo(a, b):
print('float float')
@multimethod(str, str)
def foo(a, b):
print('str str')
In [ ]:
foo(1,1)
http://blog.chadselph.com/adding-functional-style-pattern-matching-to-python.html
In [ ]:
from patternmatching import ifmatches, Any, OfType, Where
@ifmatches
def greet(gender=OfType(str), name="Joey"):
print("Joey, whats up man?")
@ifmatches
def greet(gender="male", name=Any):
print("Hello Mr. {}".format(name))
@ifmatches
def greet(gender="female", name=Any):
print("Hello Ms. {}".format(name))
@ifmatches
def greet(gender=Any, name=Where(str.isupper)):
print("Hello {}. IMPORTANT".format("Mr" if gender == 'male' else "Ms"))
@ifmatches
def greet(gender=Any, name=Any):
print("Hello, {}".format(name))
In [ ]:
greet('male', 'JAKUB')
In [ ]:
from patterns import patterns, Mismatch
@patterns
def factorial():
if 0: 1
if n is int: n * factorial(n-1)
if []: []
if [x] + xs: [factorial(x)] + factorial(xs)
if {'n': n, 'f': f}: f(factorial(n))
In [ ]:
factorial(0)
In [ ]:
factorial(5)
In [ ]:
factorial([3,4,2])
In [ ]:
factorial({'n': [5, 1], 'f': sum})
In [ ]:
factorial('hello')